package net.wanglu.www.zzz.rule.artcl;

import java.util.regex.Pattern;

import net.wanglu.www.zzz.rule.BadEgg;
import net.wanglu.www.zzz.rule.Rule;
import net.wanglu.www.zzz.service.se.np._NPTuple;
import edu.stanford.nlp.ling.TaggedWord;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.trees.tregex.TregexMatcher;
import edu.stanford.nlp.trees.tregex.TregexPattern;

public class Straits extends _ArticleRule {

	public Pattern BaseNoThe = Pattern
			.compile("\\bPass\\b|\\bPassage\\b|\\bStrait\\b");
	public Pattern StraitThe = Pattern
			.compile("\\bWetar Strait\\b|\\bLombok Strait\\b|\\bLuzon Strait\\b|\\bMare Island Strait\\b|\\bTorres Strait\\b|\\bTaiwan Strait\\b|\\bSingapore Strait\\b|\\bSan Bernardino Strait\\b|\\bQiongzhou Strait\\b|\\bMenai Strait\\b|\\bSunda Strait\\b|\\bMindoro Strait\\b|\\bMytilini Strait\\b|\\bNorthumberland Strait\\b|\\bOmbai Strait\\b|\\bPalk Strait\\b|\\bM'Clure Strait\\b|\\bBalabac Strait\\b|\\bBering Strait\\b|\\bCarquinez Strait\\b|\\bChios Strait\\b|\\bDenmark Strait\\b|\\bEuripus Strait\\b|\\bTaiwan Strait\\b|\\bHōyo Strait\\b|\\bKalmar Strait\\b|\\bKara Strait\\b|\\bKarimata Strait\\b|\\bKerch Strait\\b|\\bKitan Strait\\b|\\bKorea Strait\\b|\\bHonguedo Strait\\b");
	public Pattern PassageThe = Pattern
			.compile("\\bMona Passage\\b|\\bColvos Passage\\b|\\bDrake Passage\\b|\\bGuadeloupe Passage\\b|\\bWindward Passage\\b");

	public Pattern BaseThe = Pattern
			.compile("\\bKill\\b|\\bChannel\\b|\\bStrait of\\b|\\bStraits of\\b|\\bNarrows\\b|\\bStraits\\b|\\bEntrance\\b");
	public Pattern ChannelNoThe = Pattern
			.compile("\\bBeagle Channel\\b|\\bDalcahue Channel\\b|\\bMalta Channel\\b|\\bNicholas Channel\\b|\\bRobeson Channel\\b|\\bSaint-Barthélemy Channel\\b|\\bSt George's Channel\\b|\\bSaint Lucia Channel\\b|\\bColumbus Channel\\b|\\bTolo Channel\\b");

	public Pattern NothingNoThe = Pattern
			.compile("\\bFehmarn Belt\\b|\\bHall Basin\\b|\\bKane Basin\\b|\\bKvarken\\b|\\bMaliku Kandu\\b|\\bØresund\\b|\\bPanama\\b|\\bPearse Canal\\b|\\bPorte des Morts\\b|\\bSmith Sound\\b|\\bSouth Kvarken\\b|\\bSvinesund\\b|\\bStrait of Tartary\\b");
	public Pattern NothingThe = Pattern
			.compile("\\bSolent\\b|\\bSwale\\b|\\bSkagerrak\\b|\\bMinch\\b|\\bPentland Firth\\b|\\bPertuis d'Antioche\\b|\\bBab-el-Mandeb\\b|\\bBab Iskender\\b|\\bBosphorus\\b|\\bDardanelles\\b|\\bBocas del Dragón\\b|\\b Falkland Sound\\b|\\bGolden Gate\\b|\\bGreat Belt\\b|\\bGulf Trough\\b|\\bKill Van Kull\\b|\\bGulf of Kuşadası\\b|\\bLittle Belt\\b|\\bRiver Wantsum\\b");

	@Override
	public Object applicable(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		_NPTuple npt = (_NPTuple) objects[1];
		Tree NP = npt.getNP();
		if (NP.depth() != 2)
			return Rule.Inapplicable;// 如果不是叶子节点的父母则不符合要求
		TaggedWord headword = npt.getHeadword();
		if (headword.tag().startsWith("NN")) {
			return Rule.Applicable;// 如果中心词是名词则符合要求，否则不符合
		} else {
			return Rule.Inapplicable;
		}
	}

	@Override
	public Object deviseRightSolution(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object examine(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		if (this.applicable(objects) == Rule.Inapplicable)
			return Rule.Inapplicable;

		_NPTuple npt = (_NPTuple) objects[1];
		Tree NP = npt.getNP();

		TregexPattern pattern = null;
		TregexMatcher matcher = null;

		/*
		 * 名词短语中含有的冠词，也可能没有
		 */
		Tree dt = null;
		sb.clear();
		sb.append("/\\bDT\\b/");
		pattern = TregexPattern.compile(sb.toString());
		matcher = pattern.matcher(NP);

		/*
		 * 名词短语中
		 */
		sb.clear();
		for (TaggedWord tw : NP.taggedYield()) {
			sb.append(tw.word()).append(" ");
		}
		
		if (this.BaseThe.matcher(sb.toString()).find()) {
			if ( this.ChannelNoThe.matcher(sb.toString()).find()) {
				if (matcher.find()) {
					BadEgg egg = new BadEgg();
					egg.whereIsWrong = NP;
					egg.setProperty(BadEgg.Error);
					egg.setViolatedRule(this);
					return egg;
				} else {
					return null;
				}				
			} else {
				if (sb.toString().trim().startsWith("the")
						|| sb.toString().trim().startsWith("The")) {
					return null;
				} else {
					BadEgg egg = new BadEgg();
					egg.whereIsWrong = NP;
					egg.setProperty(BadEgg.Error);
					egg.setViolatedRule(this);
					return egg;
				}				
			}
		} else if (this.BaseNoThe.matcher(sb.toString()).find()) {
			if (this.StraitThe.matcher(sb.toString()).find()) {
				if (sb.toString().trim().startsWith("the")
						|| sb.toString().trim().startsWith("The")) {
					return null;
				} else {
					BadEgg egg = new BadEgg();
					egg.whereIsWrong = NP;
					egg.setProperty(BadEgg.Error);
					egg.setViolatedRule(this);
					return egg;
				}
			} else if (this.PassageThe.matcher(sb.toString()).find()) {
				if (sb.toString().trim().startsWith("the")
						|| sb.toString().trim().startsWith("The")) {
					return null;
				} else {
					BadEgg egg = new BadEgg();
					egg.whereIsWrong = NP;
					egg.setProperty(BadEgg.Error);
					egg.setViolatedRule(this);
					return egg;
				}
			} else {
				if (matcher.find()) {
					BadEgg egg = new BadEgg();
					egg.whereIsWrong = NP;
					egg.setProperty(BadEgg.Error);
					egg.setViolatedRule(this);
					return egg;
				} else {
					return null;
				}
			}
		} else if (this.NothingNoThe.matcher(sb.toString()).find()) {
			if (matcher.find()) {
				BadEgg egg = new BadEgg();
				egg.whereIsWrong = NP;
				egg.setProperty(BadEgg.Error);
				egg.setViolatedRule(this);
				return egg;
			} else {
				return null;
			}
		} else if (this.NothingThe.matcher(sb.toString()).find()) {
			if (sb.toString().trim().startsWith("the")
					|| sb.toString().trim().startsWith("The")) {
				return null;
			} else {
				BadEgg egg = new BadEgg();
				egg.whereIsWrong = NP;
				egg.setProperty(BadEgg.Error);
				egg.setViolatedRule(this);
				return egg;
			}
		} else {
			return Rule.Inapplicable;
		}
	}

	@Override
	public Object whyItsWrong(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		sb.append("<p>");
		sb.append("如果表达海峡使用Kill、Channel、Strait of、Straits of、Straits、Narrows、Entrance这些名词，一般前面要加定冠词the。");
		sb.append("<br>");
		sb.append("但也有例外下面用Channel描述海峡的短语不加定冠词：Beagle Channel、Dalcahue Channel、Malta Channel、Nicholas Channel、Robeson Channel、Saint-Barthélemy Channel、St George's Channel、Saint Lucia Channel、Columbus Channel、Tolo Channel");
		sb.append("<br>");
		sb.append("另外还有一些其他的描述海峡的短语需要加定冠词：The Solent、The Swale、The Skagerrak、The Minch、The Pentland Firth、The Pertuis d'Antioche、The Bab-el-Mandeb、The Bab Iskender、The Bosphorus、The Dardanelles、The Bocas del Dragón、The  Falkland Sound、The Golden Gate、The Great Belt、The Gulf Trough、The Kill Van Kull、The Gulf of Kuşadası、The Little Belt、The River Wantsum");
		sb.append("<br>");
		sb.append("如果表达海峡水道使用Pass、Passage、Strait名词，一般前面不用加定冠词。");
		sb.append("<br>");
		sb.append("但也有例外下面用Passage、Strait描述海峡的短语需要加定冠词：The Wetar Strait、The Lombok Strait、The Luzon Strait、The Mare Island Strait、The Torres Strait、The Taiwan Strait、The Singapore Strait、The San Bernardino Strait、The Qiongzhou Strait、The Menai Strait、The Sunda Strait、The Mindoro Strait、The Mytilini Strait、The Northumberland Strait、The Ombai Strait、The Palk Strait、The M'Clure Strait、The Balabac Strait、The Bering Strait、The Carquinez Strait、The Chios Strait、The Denmark Strait、The Euripus Strait、The Taiwan Strait、The Hōyo Strait、The Kalmar Strait、The Kara Strait、The Karimata Strait、The Kerch Strait、The Kitan Strait、The Korea Strait、The Mona Passage、The Colvos Passage、The Drake Passage、The Guadeloupe Passage、The Windward Passage");
		sb.append("<br>");
		sb.append("另外还有一些其他的描述海峡的短语不加定冠词：Fehmarn Belt、Hall Basin、Kane Basin、Kvarken、Maliku Kandu、Øresund、Panama、Pearse Canal、Porte des Morts、Smith Sound、South Kvarken、Svinesund、Strait of Tartary");
		sb.append("</p>");
		return sb.toString();
	}
}
